package vip.xiaonuo.biz.modular.event.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import vip.xiaonuo.biz.modular.apilog.entity.DevApiLog;
import vip.xiaonuo.biz.modular.apilog.mapper.DevApiLogMapper;
import vip.xiaonuo.biz.modular.cabinetdoor.vo.BizCabinetDoorResp;
import vip.xiaonuo.biz.modular.cabinetinfo.mapper.BizCabinetInfoMapper;
import vip.xiaonuo.biz.modular.event.entity.BizEvent;
import vip.xiaonuo.biz.modular.event.entity.BizEventConfig;
import vip.xiaonuo.biz.modular.event.mapper.BizEventConfigMapper;
import vip.xiaonuo.biz.modular.event.mapper.BizEventMapper;
import vip.xiaonuo.biz.modular.event.service.BizEventReagentService;
import vip.xiaonuo.biz.modular.event.service.BizEventReplaceService;
import vip.xiaonuo.biz.modular.event.util.EventActionUtil;
import vip.xiaonuo.biz.modular.goods.entity.BizGoods;
import vip.xiaonuo.biz.modular.goods.mapper.BizGoodsMapper;
import vip.xiaonuo.biz.modular.goods.service.BizGoodsService;
import vip.xiaonuo.common.util.AliyunSmsUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class BizEventReagentServiceImpl implements BizEventReagentService {
    @Resource
    private BizGoodsMapper bizGoodsMapper;

    @Resource
    private BizEventConfigMapper bizEventConfigMapper;

    @Resource
    private BizEventReplaceService bizEventReplaceService;

    @Resource
    private BizEventMapper bizEventMapper;

    @Resource
    private DevApiLogMapper devApiLogMapper;

    @Resource
    private BizCabinetInfoMapper bizCabinetInfoMapper;

    @Resource
    private BizGoodsService bizGoodsService;

    @Override
    public void handleExpReagent() {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("42");
        //查询过期的试剂
        List<BizGoods> list = bizGoodsMapper.getListForReagentOfExp();
        for (BizGoods item : list) {
            String eventDesc = eventConfig.getEventDesc();
            //事件描述
            eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(item));
            eventDesc = eventDesc.replace("{{exp-date}}", item.getReagentValidityPeriod());
            eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(DateUtil.date()));
            //组合实体类
            BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
            event.setEventConfigId(eventConfig.getId());
            event.setEventTime(DateUtil.date());
            event.setEventDesc(eventDesc);
            event.setGoodsId(item.getId());
            event.setEventAction(9);
            event.setCabinetGroupId(item.getCurCabinetGroupId());
            event.setCabinetId(item.getCurCabinetId());
            event.setCabinetDoorId(item.getCurCabinetDoorId());
            bizEventReplaceService.clearBizEvent(event);
            bizEventMapper.insert(event);

            //【邮件】柜门管理员
            bizEventReplaceService.sendEmailForDoorAdmin(event);
        }
    }

    @Override
    public void handleReagentInCabFirst(DevApiLog apiLog) {
        if (StringUtils.isNotBlank(apiLog.getRfids())) {
            //原始rfids
            List<String> origRfids = Arrays.asList(apiLog.getRfids().split(","));
            //根据rfids获取物品列表
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(origRfids);
            //获取试剂列表-首次入库的
            List<BizGoods> reagentList = goodsList.stream().filter(item -> item.getGoodsType() == 1 && item.getEnterFlag() == 0).collect(Collectors.toList());
            //list-首次入库未称重
            List<BizGoods> noWeighList = new ArrayList<>();
            //柜门名称
            String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("41");
            for (BizGoods goods : reagentList) {
                //获取时间点之前的称重记录
                DevApiLog devApiLog = devApiLogMapper.getLastOneForReagentWeigh(goods.getRfidNum(), apiLog.getEventTime());
                if (null != devApiLog) {
                    //更新第一次称重数据
                    bizGoodsMapper.updateFirstWeigh(goods.getId(), devApiLog.getReagentWeight(), devApiLog.getId());
                    if (goods.getReagentInitWeight() != null) {
                        //处理”试剂初始净量异常“事件
                        if (goods.getReagentInitWeight().compareTo(new BigDecimal(devApiLog.getReagentWeight())) > 0) {
                            //事件描述
                            String eventDesc = eventConfig.getEventDesc();
                            eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(goods));
                            eventDesc = eventDesc.replace("{{init-wt}}", goods.getReagentInitWeight().toString());
                            eventDesc = eventDesc.replace("{{1st-wt}}", devApiLog.getReagentWeight());
                            eventDesc = eventDesc.replace("{{cab-door}}", doorName);
                            eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                            //组合实体类
                            BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                            event.setEventConfigId(eventConfig.getId());
                            event.setEventTime(apiLog.getEventTime());
                            event.setEventDesc(eventDesc);
                            event.setGoodsId(goods.getId());
                            event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                            event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                            event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                            event.setCabinetDoorId(cabinetDoorResp.getId());
                            event.setEventUserId(apiLog.getUserId());
                            event.setAdminId(apiLog.getAdminId());
                            bizEventReplaceService.clearBizEvent(event);
                            bizEventMapper.insert(event);

                            //【邮件+短信】柜门管理员
                            bizEventReplaceService.sendEmailForDoorAdmin(event);
                            Map<String, String> content = new HashMap<>();
                            content.put("reagentName", bizEventReplaceService.getGoodsNameForEntity(goods));
                            content.put("reagentWeght", goods.getReagentInitWeight().toString());
                            content.put("reagentInitWeght", devApiLog.getReagentWeight());
                            content.put("cabinetName", doorName);
                            content.put("checkTime", DateUtil.formatDateTime(apiLog.getEventTime()));
                            bizEventReplaceService.sendSmsForDoorAdmin(event, AliyunSmsUtil.ABNORMAL_NETWEIGHT_REAGENT, content);
                        }
                        //计算容器重量
                        bizGoodsService.handleReagentFistAvlData(goods, devApiLog.getReagentWeight());
                    }
                } else {
                    //首次入库未称重
                    noWeighList.add(goods);
                }
            }
            this.addRecordForNoWeigh(noWeighList, apiLog, doorName, cabinetDoorResp);

        }
    }

    @Override
    public void handleReagentClassClash(DevApiLog apiLog) {
        if (StringUtils.isNotBlank(apiLog.getRfids())) {
            //原始rfids
            List<String> origRfids = Arrays.asList(apiLog.getRfids().split(","));
            //根据rfids获取物品列表
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(origRfids);
            //获取试剂列表-首次入库的
            List<BizGoods> reagentList = goodsList.stream().filter(item -> item.getGoodsType() == 1).collect(Collectors.toList());
            //list-试剂存储类型冲突
            List<BizGoods> clashList = new ArrayList<>();
            //柜门名称
            String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (BizGoods goods : reagentList) {
                if (goods.getUnknownFlag() == 0) {
                    if (StringUtils.isNotBlank(cabinetDoorResp.getReagentStorageType())) {
                        //存放试剂类型冲突
                        if (!cabinetDoorResp.getReagentStorageType().equals(goods.getReagentClassId())) {
                            clashList.add(goods);
                        }
                    }
                }
            }
            this.addRecordForClassClash(clashList, apiLog, doorName, cabinetDoorResp);
        }
    }

    @Override
    public void handleCabWeight(List<String> rfids, DevApiLog apiLog) {
        //柜子信息
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        //计算当前柜子在柜的试剂重量
        String totlaWeigh = bizGoodsMapper.totalWeighInCab(cabinetDoorResp.getCabinetInfoId());
        //转换为kg
        BigDecimal curWeigh = NumberUtil.div(totlaWeigh, "1000", 4);
        //更新柜子当前重量
        bizCabinetInfoMapper.updateCabCurSto(cabinetDoorResp.getCabinetInfoId(), curWeigh.toString());
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("39");
        if (StringUtils.isNotBlank(cabinetDoorResp.getReagentStorageMax())) {
            if (new BigDecimal(cabinetDoorResp.getReagentStorageMax()).compareTo(curWeigh) < 0 && !rfids.isEmpty()) {
                //根据rfids获取物品列表
                List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(rfids);
                //柜子名称
                String cabName = bizEventReplaceService.getCabName(apiLog.getCabinetCode());
                //操作人
                String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
                for (BizGoods goods : goodsList) {
                    String eventDesc = eventConfig.getEventDesc();
                    //事件描述
                    eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(goods));
                    eventDesc = eventDesc.replace("{{cab}}", cabName);
                    eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                    eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
                    eventDesc = eventDesc.replace("{{user}}", userName);
                    if (StringUtils.isNotBlank(apiLog.getAdminId())) {
                        String adminName = bizEventReplaceService.getUserName(apiLog.getAdminId());
                        eventDesc = eventDesc.replace("{{admin}}", adminName);
                    } else {
                        eventDesc = eventDesc.replace(",{{admin}}", "");
                    }
                    //组合实体类
                    BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                    event.setEventConfigId(eventConfig.getId());
                    event.setEventTime(apiLog.getEventTime());
                    event.setEventDesc(eventDesc);
                    event.setGoodsId(goods.getId());
                    event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                    event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                    event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                    event.setCabinetDoorId(cabinetDoorResp.getId());
                    event.setEventUserId(apiLog.getUserId());
                    event.setAdminId(apiLog.getAdminId());
                    bizEventReplaceService.clearBizEvent(event);
                    bizEventMapper.insert(event);

                    //【邮件+短信】本次刷卡开门的卡主，柜门管理员
                    bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
                    bizEventReplaceService.sendEmailForDoorAdmin(event);

                    Map<String, String> content = new HashMap<>();
                    content.put("reagentName", bizEventReplaceService.getGoodsNameForEntity(goods));
                    content.put("cabinet", cabName);
                    content.put("checkTime", DateUtil.formatDateTime(apiLog.getEventTime()));
                    content.put("operator", userName);
                    bizEventReplaceService.sendSmsForUser(apiLog.getUserId(), event, AliyunSmsUtil.REAGENT_CABINET_EMC, content);
                    bizEventReplaceService.sendSmsForDoorAdmin(event, AliyunSmsUtil.REAGENT_CABINET_EMC, content);
                }
            }
        }
    }

    @Override
    public void handleRtnWeighCount(List<BizGoods> goodsList, DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("38");
        //柜子信息
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        //操作人
        String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
        for (BizGoods goods : goodsList) {
            String eventDesc = eventConfig.getEventDesc();
            //事件描述
            eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(goods));
            eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
            eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
            eventDesc = eventDesc.replace("{{user}}", userName);
            if (StringUtils.isNotBlank(apiLog.getAdminId())) {
                String adminName = bizEventReplaceService.getUserName(apiLog.getAdminId());
                eventDesc = eventDesc.replace("{{admin}}", adminName);
            } else {
                eventDesc = eventDesc.replace(",{{admin}}", "");
            }
            //组合实体类
            BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
            event.setApiLogId(apiLog.getId());
            event.setEventConfigId(eventConfig.getId());
            event.setEventTime(apiLog.getEventTime());
            event.setEventDesc(eventDesc);
            event.setGoodsId(goods.getId());
            event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
            event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
            event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
            event.setCabinetDoorId(cabinetDoorResp.getId());
            event.setEventUserId(apiLog.getUserId());
            event.setAdminId(apiLog.getAdminId());
            bizEventReplaceService.clearBizEvent(event);
            bizEventMapper.insert(event);

            //【邮件】本次刷卡开门的卡主，柜门管理员
            bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
            bizEventReplaceService.sendEmailForDoorAdmin(event);
        }
    }

    /**
     * 添加记录-首次入库未称重
     *
     * @param goodsList
     * @param apiLog
     */
    private void addRecordForNoWeigh(List<BizGoods> goodsList, DevApiLog apiLog, String doorName, BizCabinetDoorResp cabinetDoorResp) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("37");
        for (BizGoods item : goodsList) {
            String eventDesc = eventConfig.getEventDesc();
            //事件描述
            eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(item));
            eventDesc = eventDesc.replace("{{cab-door}}", doorName);
            eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
            eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
            //操作人
            String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
            eventDesc = eventDesc.replace("{{user}}", userName);
            if (StringUtils.isNotBlank(apiLog.getAdminId())) {
                String adminName = bizEventReplaceService.getUserName(apiLog.getAdminId());
                eventDesc = eventDesc.replace("{{admin}}", adminName);
            } else {
                eventDesc = eventDesc.replace(",{{admin}}", "");
            }
            //组合实体类
            BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
            event.setEventConfigId(eventConfig.getId());
            event.setEventTime(apiLog.getEventTime());
            event.setEventDesc(eventDesc);
            event.setGoodsId(item.getId());
            event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
            event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
            event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
            event.setCabinetDoorId(cabinetDoorResp.getId());
            event.setEventUserId(apiLog.getUserId());
            event.setAdminId(apiLog.getAdminId());
            bizEventReplaceService.clearBizEvent(event);
            bizEventMapper.insert(event);

            //【邮件】本次刷卡开门的卡主，柜门管理员
            bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
            bizEventReplaceService.sendEmailForDoorAdmin(event);
        }
    }

    /**
     * 添加记录-试剂存储属性冲突
     *
     * @param goodsList
     * @param apiLog
     */
    private void addRecordForClassClash(List<BizGoods> goodsList, DevApiLog apiLog, String doorName, BizCabinetDoorResp cabinetDoorResp) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("40");
        for (BizGoods item : goodsList) {
            String eventDesc = eventConfig.getEventDesc();
            //事件描述
            eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(item));
            eventDesc = eventDesc.replace("{{cab-door}}", doorName);
            eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
            eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
            //操作人
            String userName = bizEventReplaceService.getUserName(apiLog.getUserId());

            eventDesc = eventDesc.replace("{{user}}", userName);
            if (StringUtils.isNotBlank(apiLog.getAdminId())) {
                String adminName = bizEventReplaceService.getUserName(apiLog.getAdminId());
                eventDesc = eventDesc.replace("{{admin}}", adminName);
            } else {
                eventDesc = eventDesc.replace(",{{admin}}", "");
            }
            //组合实体类
            BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
            event.setEventConfigId(eventConfig.getId());
            event.setEventTime(apiLog.getEventTime());
            event.setEventDesc(eventDesc);
            event.setGoodsId(item.getId());
            event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
            event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
            event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
            event.setCabinetDoorId(cabinetDoorResp.getId());
            event.setEventUserId(apiLog.getUserId());
            event.setAdminId(apiLog.getAdminId());
            bizEventReplaceService.clearBizEvent(event);
            bizEventMapper.insert(event);

            //【邮件+短信】本次刷卡开门的卡主，柜门管理员
            bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
            bizEventReplaceService.sendEmailForDoorAdmin(event);

            Map<String, String> content = new HashMap<>();
            content.put("reagentName", bizEventReplaceService.getGoodsNameForEntity(item));
            content.put("cabinet", doorName);
            content.put("checkTIme", DateUtil.formatDateTime(apiLog.getEventTime()));
            content.put("operator", userName);
            bizEventReplaceService.sendSmsForUser(apiLog.getUserId(), event, AliyunSmsUtil.REAGENT_STORAGE_CONFLICTS, content);
            bizEventReplaceService.sendSmsForDoorAdmin(event, AliyunSmsUtil.REAGENT_STORAGE_CONFLICTS, content);
        }
    }
}
